import SongRequestManager = require("services/songRequestManager");
import SongPlayer = require("services/songPlayer");
import Song = require("models/song");
import AudioStatus = require("common/audioStatus");
import GetSongCommand = require("commands/getSongCommand");
import GetSongMatchesCommand = require("commands/getSongMatchesCommand");
import GetArtistBioCommand = require("commands/getArtistBioCommand");

class Home {
    player = new SongPlayer();
    songRequestManager = new SongRequestManager();
    selectedSongRequest = ko.observable<Song>();
    songRequestMatches = ko.observableArray<Song>();
    songRequestText = ko.observable('');
    isPaused: KnockoutComputed<boolean>;
    twitterShareLink: KnockoutComputed<string>;
    currentArtistBio = ko.observable<string>();

    constructor() {
        this.songRequestText.extend({ throttle: 500 }).subscribe(searchText => this.getSongMatches(searchText));
        this.isPaused = ko.computed(() => this.player.status() === AudioStatus.Paused);
        this.player.status.subscribe(s => this.songStatusChanged(s));
        this.player.song.subscribe(s => this.currentSongChanged(s));
        this.twitterShareLink = ko.computed(() => {
            var songToShare = this.player.song();
            if (songToShare) {
                var tweetText = 'Listening to "' + songToShare.artist + " - " + songToShare.name + '"';
                var url = window.location.href + "?song=" + songToShare.id;
                var via = "bitshuva";
                return "https://twitter.com/share?text=" + encodeURIComponent(tweetText) + "&url=" + encodeURIComponent(url) + "&via=" + encodeURIComponent(via);
            }
            return "#";
        });
    }

    attached() {
        var audioElement = <HTMLAudioElement>document.querySelector("audio");
        this.player.initialize(audioElement);

        this.playNextSong();
    }

    playPause() {
        if (this.player.status() === AudioStatus.Playing) {
            this.player.pause();
        } else {
            this.player.resume();
        }
    }

    requestSelectedSong() {
        var selectedSong = this.selectedSongRequest();
        if (selectedSong) {
            this.player.pause();
            this.songRequestManager.requestSong(selectedSong);
            this.playNextSong();
        }

        this.selectedSongRequest(null);
        this.songRequestText("");
    }

    songRequestMatchClicked(song) {
        this.selectedSongRequest(song);
        this.songRequestText(song.artist + " - " + song.name);
        this.songRequestMatches.removeAll();
    }

    playNextSong() {
        this.player.pause();

        // If we've got a song request, play that.
        if (this.songRequestManager.hasPendingRequest()) {
            this.songRequestManager.playRequest(this.player);
        }
        else {
            new GetSongCommand()
                .execute()
                .done((song: Song) => {
                    this.player.playNewSong(song);
                    this.songRequestManager.removePendingSongRequest(song.id);
                });
        }
    }

    resetSongRequestDialog() {
        this.selectedSongRequest(null);
        this.songRequestText("");
        this.songRequestMatches([]);
    }

    songStatusChanged(status: AudioStatus) {
        if (status === AudioStatus.Ended) {
            this.playNextSong();
        }

        var errorStates = [AudioStatus.Erred, AudioStatus.Stalled, AudioStatus.Aborted];
        if (errorStates.indexOf(status) !== -1) {
            // Wait 3 seconds and if we're still stuck on this song, move to the next.
            var currentSong = this.player.song();
            setTimeout(() => {
                if (this.player.song() === currentSong) {
                    this.playNextSong();
                }
            }, 3000);
        }
    }

    getSongMatches(searchText: string) {
        if (searchText && searchText.length > 2) {
            new GetSongMatchesCommand(searchText)
                .execute()
                .done((songs: Song[]) => {
                    var isWaitingOnThisQuery = this.songRequestText() === searchText;
                    if (isWaitingOnThisQuery) {
                        this.songRequestMatches(songs);
                    }
                });
        }
    }

    likeCurrentSong() {
        var song = this.player.song();
        if (song) {
            song.like();
        }
    }

    dislikeCurrentSong() {
        var song = this.player.song();
        if (song) {
            song.dislike();
        }
    }

    currentSongChanged(song: Song) {
        this.currentArtistBio(" ");
        if (song) {
            new GetArtistBioCommand(song.artist)
                .execute()
                .done((bio: string) => {
                    if (this.player.song() == song) {
                        this.currentArtistBio(bio);
                    }
                });
        }
    }
}

export = Home;